﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KZ.Express.H.BLL;
using KZ.Utilities;
using System.Data;
using KZ.Express.H.ENT;

namespace KZ.Express.H.Presenter
{
    public interface IOrderListView : IBaseView
    {
        int OrderID { get; }

        List<DataRow> ChangedRows { get; }
    }

    public interface IAdminOrderListView : IOrderListView
    {
        DataTable PriceLists { get; }
    }

    public class OrderPresenter : BasePresenter, IBasePresenter
    {
        public OrderPresenter(IOrderListView view)
            : base(view)
        {
            _view = view;
            _baseBLL = new OrderBLL();
        }

        public OrderPresenter(IOrderListView view, IBaseBLL baseBLL)
            : base(view, baseBLL)
        {
            _view = view;
            _baseBLL = baseBLL;
        }

        public void UpdateCustomer()
        {
            IOrderListView view = _view as IOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                string customerName = Utility.StringParse(rows[0]["CustomerName"]);

                SearchCriteria search = new SearchCriteria();
                search.Add("ExactCustomerName", customerName);

                CustomerENT customer = _baseBLL.GetEntity<CustomerENT>(search);

                if (customer != null)
                {
                    rows[0]["SaleID"] = customer.UserID;
                    rows[0]["SaleName"] = customer.SaleName;
                    rows[0]["CustomerID"] = customer.CustomerID;
                    rows[0]["CustomerName"] = customer.CustomerName;
                }
                else
                {
                    rows[0]["SaleID"] = DBNull.Value;
                    rows[0]["SaleName"] = DBNull.Value;
                    rows[0]["CustomerID"] = DBNull.Value;
                    rows[0]["CustomerName"] = DBNull.Value;

                    throw new BusinessLogicException("Mã khách hàng không tồn tại");
                }
            }
        }

        public void UpdateCountry()
        {
            IOrderListView view = _view as IOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                string countryName = Utility.StringParse(rows[0]["CountryName"]);

                SearchCriteria search = new SearchCriteria();
                search.Add("ExactCountryName", countryName);

                CountryENT country = _baseBLL.GetEntity<CountryENT>(search);

                if (country != null)
                {
                    rows[0]["CountryID"] = country.CountryID;
                    rows[0]["CountryName"] = country.CountryName;
                }
                else
                {
                    rows[0]["CountryID"] = DBNull.Value;
                    rows[0]["CountryName"] = DBNull.Value;

                    throw new BusinessLogicException("Tên nước không tồn tại");
                }
            }
        }

        public void UpdateCarrier()
        {
            IOrderListView view = _view as IOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                string carrierName = Utility.StringParse(rows[0]["CarrierName"]);

                SearchCriteria search = new SearchCriteria();
                search.Add("ExactCarrierName", carrierName);

                CarrierENT carrier = _baseBLL.GetEntity<CarrierENT>(search);

                if (carrier != null)
                {
                    rows[0]["CarrierID"] = carrier.CarrierID;
                    rows[0]["CarrierName"] = carrier.CarrierName;
                }
                else
                {
                    rows[0]["CarrierID"] = DBNull.Value;
                    rows[0]["CarrierName"] = DBNull.Value;

                    throw new BusinessLogicException("Tên dịch vụ không tồn tại");
                }
            }
        }

        public void UpdateSupplier()
        {
            IOrderListView view = _view as IOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                string supplierName = Utility.StringParse(rows[0]["SupplierName"]);

                SearchCriteria search = new SearchCriteria();
                search.Add("ExactSupplierName", supplierName);

                SupplierENT supplier = _baseBLL.GetEntity<SupplierENT>(search);

                if (supplier != null)
                {
                    rows[0]["SupplierID"] = supplier.SupplierID;
                    rows[0]["SupplierName"] = supplier.SupplierName;
                }
                else
                {
                    rows[0]["SupplierID"] = DBNull.Value;
                    rows[0]["SupplierName"] = DBNull.Value;

                    throw new BusinessLogicException("Tên nhà cung cấp không tồn tại");
                }
            }
        }

        public void UpdateSale()
        {
            IOrderListView view = _view as IOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                string saleName = Utility.StringParse(rows[0]["SaleName"]);

                SearchCriteria search = new SearchCriteria();
                search.Add("ExactFullName", saleName);
                search.Add("RoleID", 2);

                UserENT user = _baseBLL.GetEntity<UserENT>(search);

                if (user != null)
                {
                    rows[0]["SaleID"] = user.UserID;
                    rows[0]["SaleName"] = user.FullName;
                }
                else
                {
                    rows[0]["SaleID"] = DBNull.Value;
                    rows[0]["SaleName"] = DBNull.Value;

                    throw new BusinessLogicException("Tên nhân viên sale không tồn tại");
                }
            }
        }

        public void CheckSupplierCarrier()
        {
        }

        public void AddChangedRow()
        {
            IOrderListView view = _view as IOrderListView;
            if (_view.Table != null)
            {
                DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
                if (rows.Length > 0 && !view.ChangedRows.Contains(rows[0]))
                    view.ChangedRows.Add(rows[0]);
            }
        }
    }

    public class CSOrderPresenter : OrderPresenter
    {
        public CSOrderPresenter(IOrderListView view)
            : base(view)
        {
        }

        public CSOrderPresenter(IOrderListView view, IBaseBLL baseBLL)
            : base(view, baseBLL)
        {
        }

        public override void Save()
        {
            try
            {
                IOrderListView view = _view as IOrderListView;

                (_baseBLL as OrderBLL).SaveCS(view.ChangedRows);
                view.ChangedRows.Clear();
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
            catch (BusinessLogicException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }
    }

    public class SaleOrderPresenter : OrderPresenter
    {
        public SaleOrderPresenter(IOrderListView view)
            : base(view)
        {
        }

        public SaleOrderPresenter(IOrderListView view, IBaseBLL baseBLL)
            : base(view, baseBLL)
        {
        }

        public override void Save()
        {
            try
            {
                IOrderListView view = _view as IOrderListView;

                (_baseBLL as OrderBLL).SaveSale(view.ChangedRows);
                view.ChangedRows.Clear();
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
            catch (BusinessLogicException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        /// <summary>
        /// cập nhật list price => cập nhật fuel và vat
        /// </summary>
        public void UpdateListPrice()
        {
            IOrderListView view = _view as IOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                decimal listPrice = Utility.DecimalParse(rows[0]["ListPrice"]);
                decimal? fuelPercent = Utility.DecimalNParse(rows[0]["FuelPercent"]);
                decimal? vatPercent = Utility.DecimalNParse(rows[0]["VATPercent"]);

                decimal fuel = listPrice * fuelPercent ?? 0;
                decimal vat = (listPrice + fuel) * vatPercent ?? 0;

                if (listPrice == 0) rows[0]["ListPrice"] = DBNull.Value;
                else rows[0]["ListPrice"] = listPrice;

                if (fuel == 0) rows[0]["Fuel"] = DBNull.Value;
                else rows[0]["Fuel"] = fuel;

                if (vat == 0) rows[0]["VAT"] = DBNull.Value;
                else rows[0]["VAT"] = vat;

                if (listPrice + fuel + vat == 0) rows[0]["TotalRate"] = DBNull.Value;
                else rows[0]["TotalRate"] = listPrice + fuel + vat;
            }
        }

        /// <summary>
        /// cập nhật fuel => cập nhật vat
        /// </summary>
        public void UpdateFuel()
        {
            IOrderListView view = _view as IOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                decimal listPrice = Utility.DecimalParse(rows[0]["ListPrice"]);
                decimal? fuelPercent = Utility.DecimalNParse(rows[0]["Fuel"]);
                decimal? vatPercent = Utility.DecimalNParse(rows[0]["VATPercent"]);

                decimal fuel = listPrice * fuelPercent ?? 0;
                decimal vat = (listPrice + fuel) * vatPercent ?? 0;

                if (!fuelPercent.HasValue) rows[0]["FuelPercent"] = DBNull.Value;
                else rows[0]["FuelPercent"] = fuelPercent;

                if (fuel == 0) rows[0]["Fuel"] = DBNull.Value;
                else rows[0]["Fuel"] = fuel;

                if (vat == 0) rows[0]["VAT"] = DBNull.Value;
                else rows[0]["VAT"] = vat;

                if (listPrice + fuel + vat == 0) rows[0]["TotalRate"] = DBNull.Value;
                else rows[0]["TotalRate"] = listPrice + fuel + vat;
            }
        }

        /// <summary>
        /// cập nhật vat
        /// </summary>
        public void UpdateVAT()
        {
            IOrderListView view = _view as IOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                decimal listPrice = Utility.DecimalParse(rows[0]["ListPrice"]);
                decimal fuel = Utility.DecimalParse(rows[0]["Fuel"]);
                decimal? vatPercent = Utility.DecimalNParse(rows[0]["VAT"]);

                decimal vat = (listPrice + fuel) * vatPercent ?? 0;

                if (!vatPercent.HasValue) rows[0]["VATPercent"] = DBNull.Value;
                else rows[0]["VATPercent"] = vatPercent;

                if (vat == 0) rows[0]["VAT"] = DBNull.Value;
                else rows[0]["VAT"] = vat;

                if (listPrice + fuel + vat == 0) rows[0]["TotalRate"] = DBNull.Value;
                else rows[0]["TotalRate"] = listPrice + fuel + vat;
            }
        }
    }

    public class AccountOrderPresenter : OrderPresenter
    {
        public AccountOrderPresenter(IOrderListView view)
            : base(view)
        {
        }

        public AccountOrderPresenter(IOrderListView view, IBaseBLL baseBLL)
            : base(view, baseBLL)
        {
        }

        public override void Save()
        {
            try
            {
                IOrderListView view = _view as IOrderListView;

                (_baseBLL as OrderBLL).SaveAccount(view.ChangedRows);
                view.ChangedRows.Clear();
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
            catch (BusinessLogicException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        /// <summary>
        /// cập nhật list price => cập nhật fuel và vat
        /// </summary>
        public void UpdateListPrice()
        {
            IOrderListView view = _view as IOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                decimal listPrice = Utility.DecimalParse(rows[0]["ListPrice"]);
                decimal? fuelPercent = Utility.DecimalNParse(rows[0]["FuelPercent"]);
                decimal? vatPercent = Utility.DecimalNParse(rows[0]["VATPercent"]);

                decimal fuel = listPrice * fuelPercent ?? 0;
                decimal vat = (listPrice + fuel) * vatPercent ?? 0;

                if (listPrice == 0) rows[0]["ListPrice"] = DBNull.Value;
                else rows[0]["ListPrice"] = listPrice;

                if (fuel == 0) rows[0]["Fuel"] = DBNull.Value;
                else rows[0]["Fuel"] = fuel;

                if (vat == 0) rows[0]["VAT"] = DBNull.Value;
                else rows[0]["VAT"] = vat;

                if (listPrice + fuel + vat == 0) rows[0]["TotalRate"] = DBNull.Value;
                else rows[0]["TotalRate"] = listPrice + fuel + vat;
            }
        }

        /// <summary>
        /// cập nhật fuel => cập nhật vat
        /// </summary>
        public void UpdateFuel()
        {
            IOrderListView view = _view as IOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                decimal listPrice = Utility.DecimalParse(rows[0]["ListPrice"]);
                decimal? fuelPercent = Utility.DecimalNParse(rows[0]["Fuel"]);
                decimal? vatPercent = Utility.DecimalNParse(rows[0]["VATPercent"]);

                decimal fuel = listPrice * fuelPercent ?? 0;
                decimal vat = (listPrice + fuel) * vatPercent ?? 0;

                if (!fuelPercent.HasValue) rows[0]["FuelPercent"] = DBNull.Value;
                else rows[0]["FuelPercent"] = fuelPercent;

                if (fuel == 0) rows[0]["Fuel"] = DBNull.Value;
                else rows[0]["Fuel"] = fuel;

                if (vat == 0) rows[0]["VAT"] = DBNull.Value;
                else rows[0]["VAT"] = vat;

                if (listPrice + fuel + vat == 0) rows[0]["TotalRate"] = DBNull.Value;
                else rows[0]["TotalRate"] = listPrice + fuel + vat;
            }
        }

        /// <summary>
        /// cập nhật vat
        /// </summary>
        public void UpdateVAT()
        {
            IOrderListView view = _view as IOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                decimal listPrice = Utility.DecimalParse(rows[0]["ListPrice"]);
                decimal fuel = Utility.DecimalParse(rows[0]["Fuel"]);
                decimal? vatPercent = Utility.DecimalNParse(rows[0]["VAT"]);

                decimal vat = (listPrice + fuel) * vatPercent ?? 0;

                if (!vatPercent.HasValue) rows[0]["VATPercent"] = DBNull.Value;
                else rows[0]["VATPercent"] = vatPercent;

                if (vat == 0) rows[0]["VAT"] = DBNull.Value;
                else rows[0]["VAT"] = vat;

                if (listPrice + fuel + vat == 0) rows[0]["TotalRate"] = DBNull.Value;
                else rows[0]["TotalRate"] = listPrice + fuel + vat;
            }
        }
    }

    public class AdminOrderPresenter : OrderPresenter
    {
        public AdminOrderPresenter(IOrderListView view)
            : base(view)
        {
        }

        public AdminOrderPresenter(IOrderListView view, IBaseBLL baseBLL)
            : base(view, baseBLL)
        {
        }

        public override void Save()
        {
            try
            {
                IOrderListView view = _view as IOrderListView;

                (_baseBLL as OrderBLL).SaveAdmin(view.ChangedRows);
                view.ChangedRows.Clear();
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
            catch (BusinessLogicException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        /// <summary>
        /// Chọn bảng giá khi cập nhật khối lượng hay dịch vụ
        /// </summary>
        public void UpdatePriceList()
        {
            IAdminOrderListView view = _view as IAdminOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                int? priceListID = Utility.IntNParse(rows[0]["OriginalPriceListID"]);
                int? carrierID = Utility.IntNParse(rows[0]["CarrierID"]);
                int? supplierID = Utility.IntNParse(rows[0]["SupplierID"]);
                int? countryID = Utility.IntNParse(rows[0]["CountryID"]);
                decimal? weight = Utility.DecimalNParse(rows[0]["Weight"]);
                string type = Utility.StringParse(rows[0]["Type"]);

                if (!priceListID.HasValue && carrierID.HasValue && supplierID.HasValue)
                {
                    DataRow[] priceList = view.PriceLists.Select("CarrierID = " + carrierID + " AND SupplierID = " + supplierID);
                    if (priceList.Length > 0)
                    {
                        priceListID = Utility.IntNParse(priceList[0]["PriceListID"]);
                        rows[0]["OriginalPriceListID"] = priceListID;
                    }
                }

                if (priceListID.HasValue && countryID.HasValue && weight.HasValue)
                {
                    SearchCriteria search = new SearchCriteria();
                    search.Add("PriceListID", priceListID);
                    search.Add("Weight", weight);
                    search.Add("Type", type);
                    search.Add("CountryID", countryID);
                    Dictionary<string, object> price = _baseBLL.ExecuteNonQuery(PriceListDetailENT.SelectPriceProcedure, search, "Price");

                    rows[0]["StandardPrice"] = price["Price"];
                }
            }
        }

        public void UpdateStandardPrice()
        {
            IAdminOrderListView view = _view as IAdminOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                int? priceListID = Utility.IntNParse(rows[0]["OriginalPriceListID"]);
                int? countryID = Utility.IntNParse(rows[0]["CountryID"]);
                decimal? weight = Utility.DecimalNParse(rows[0]["Weight"]);
                string type = Utility.StringParse(rows[0]["Type"]);

                if (priceListID.HasValue && countryID.HasValue && weight.HasValue)
                {
                    SearchCriteria search = new SearchCriteria();
                    search.Add("PriceListID", priceListID);
                    search.Add("Weight", weight);
                    search.Add("Type", type);
                    search.Add("CountryID", countryID);
                    Dictionary<string, object> price = _baseBLL.ExecuteNonQuery(PriceListDetailENT.SelectPriceProcedure, search, "Price");

                    rows[0]["StandardPrice"] = price["Price"];
                }
                else
                    rows[0]["StandardPrice"] = DBNull.Value;
            }
        }

        /// <summary>
        /// cập nhật list price => cập nhật fuel và vat
        /// </summary>
        public void UpdateListPrice()
        {
            IAdminOrderListView view = _view as IAdminOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                decimal listPrice = Utility.DecimalParse(rows[0]["ListPrice"]);
                decimal? fuelPercent = Utility.DecimalNParse(rows[0]["FuelPercent"]);
                decimal? vatPercent = Utility.DecimalNParse(rows[0]["VATPercent"]);

                decimal fuel = listPrice * fuelPercent ?? 0;
                decimal vat = (listPrice + fuel) * vatPercent ?? 0;

                if (listPrice == 0) rows[0]["ListPrice"] = DBNull.Value;
                else rows[0]["ListPrice"] = listPrice;

                if (fuel == 0) rows[0]["Fuel"] = DBNull.Value;
                else rows[0]["Fuel"] = fuel;

                if (vat == 0) rows[0]["VAT"] = DBNull.Value;
                else rows[0]["VAT"] = vat;

                if (listPrice + fuel + vat == 0) rows[0]["TotalRate"] = DBNull.Value;
                else rows[0]["TotalRate"] = listPrice + fuel + vat;

                UpdateProfit(rows[0]);
            }
        }

        /// <summary>
        /// cập nhật fuel => cập nhật vat
        /// </summary>
        public void UpdateFuel()
        {
            IAdminOrderListView view = _view as IAdminOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                decimal listPrice = Utility.DecimalParse(rows[0]["ListPrice"]);
                decimal? fuelPercent = Utility.DecimalNParse(rows[0]["Fuel"]);
                decimal? vatPercent = Utility.DecimalNParse(rows[0]["VATPercent"]);

                decimal fuel = listPrice * fuelPercent ?? 0;
                decimal vat = (listPrice + fuel) * vatPercent ?? 0;

                if (!fuelPercent.HasValue) rows[0]["FuelPercent"] = DBNull.Value;
                else rows[0]["FuelPercent"] = fuelPercent;

                if (fuel == 0) rows[0]["Fuel"] = DBNull.Value;
                else rows[0]["Fuel"] = fuel;

                if (vat == 0) rows[0]["VAT"] = DBNull.Value;
                else rows[0]["VAT"] = vat;

                if (listPrice + fuel + vat == 0) rows[0]["TotalRate"] = DBNull.Value;
                else rows[0]["TotalRate"] = listPrice + fuel + vat;

                UpdateProfit(rows[0]);
            }
        }

        /// <summary>
        /// cập nhật vat
        /// </summary>
        public void UpdateVAT()
        {
            IAdminOrderListView view = _view as IAdminOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                decimal listPrice = Utility.DecimalParse(rows[0]["ListPrice"]);
                decimal fuel = Utility.DecimalParse(rows[0]["Fuel"]);
                decimal? vatPercent = Utility.DecimalNParse(rows[0]["VAT"]);

                decimal vat = (listPrice + fuel) * vatPercent ?? 0;

                if (!vatPercent.HasValue) rows[0]["VATPercent"] = DBNull.Value;
                else rows[0]["VATPercent"] = vatPercent;

                if (vat == 0) rows[0]["VAT"] = DBNull.Value;
                else rows[0]["VAT"] = vat;

                if (listPrice + fuel + vat == 0) rows[0]["TotalRate"] = DBNull.Value;
                else rows[0]["TotalRate"] = listPrice + fuel + vat;

                UpdateProfit(rows[0]);
            }
        }

        public void UpdateCost()
        {
            IAdminOrderListView view = _view as IAdminOrderListView;
            DataRow[] rows = _view.Table.Select("OrderID = " + view.OrderID);
            if (rows.Length > 0)
            {
                decimal commission = Utility.DecimalParse(rows[0]["Commission"]);
                decimal carrier = Utility.DecimalParse(rows[0]["Carrier"]);
                decimal handlingfee = Utility.DecimalParse(rows[0]["HandlingFee"]);
                decimal standardPrice = Utility.DecimalParse(rows[0]["StandardPrice"]);

                if (commission == 0) rows[0]["Commission"] = DBNull.Value;
                else rows[0]["Commission"] = commission;

                if (carrier == 0) rows[0]["Carrier"] = DBNull.Value;
                else rows[0]["Carrier"] = carrier;

                if (handlingfee == 0) rows[0]["HandlingFee"] = DBNull.Value;
                else rows[0]["HandlingFee"] = handlingfee;

                if (standardPrice == 0) rows[0]["StandardPrice"] = DBNull.Value;
                else rows[0]["StandardPrice"] = standardPrice;

                UpdateProfit(rows[0]);
            }
        }

        public void UpdateProfit(DataRow row)
        {
            decimal totalRate = Utility.DecimalParse(row["TotalRate"]);
            decimal commission = Utility.DecimalParse(row["Commission"]);
            decimal carrier = Utility.DecimalParse(row["Carrier"]);
            decimal handlingfee = Utility.DecimalParse(row["HandlingFee"]);
            decimal standardPrice = Utility.DecimalParse(row["StandardPrice"]);

            if (totalRate - commission - carrier - handlingfee - standardPrice == 0) row["Profit"] = DBNull.Value;
            else row["Profit"] = totalRate - commission - carrier - handlingfee - standardPrice;
        }
    }
}
